/*
 * Timetable.java
 * 
 * Copyright 2008 David D. Emory
 * 
 * This file is part of Five Points. See <http://www.fpdev.org> for
 * additional information regarding the project.
 * 
 * Five Points is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Five Points is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Five Points.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.fpdev.core.transit;

import java.io.Serializable;

public class Timetable implements Serializable {

  //private DayOfWeek day_;
  private CalendarService service_;
  private int[][] table_;
  private String filename_;
  private boolean fileSaved_;
  
  /*public enum DayOfWeek {
    WEEKDAY (1, "Weekday", "w", "w"), 
    SATURDAY (2, "Saturday", "sat", "sa"), 
    SUNDAY (3, "Sunday", "sun", "su");
    
    private final int numCode_;
    private final String name_, strCode_, fileCode_; // TODO: deprecate filecode
    
    DayOfWeek(int numCode, String name, String code, String fileCode) {
      numCode_ = numCode; name_ = name; strCode_ = code; fileCode_ = fileCode;
    }
  
    public int numCode() { return numCode_; }
    public String fullName() { return name_; }
    public String strCode() { return strCode_; }
    public String fileCode() { return fileCode_; }
            
  }*/

  public Timetable(CalendarService service, int runs, int stops, boolean fileSaved) {
    service_ = service;
    init(runs, stops);
    fileSaved_ = fileSaved;
  }

  public void init(int runs, int stops) {
    table_ = new int[runs][stops];
  //System.out.printf("init table %d by %d\n", runs, stops);
  }

  /*public DayOfWeek getDay() {
    return day_;
  }*/

  public CalendarService getService() {
    return service_;
  }

  public String getFilename() {
    return filename_;
  }

  public void setFilename(String filename) {
    filename_ = filename;
  }

  public boolean isFileSaved() {
    return fileSaved_;
  }

  public void setFileSaved(boolean fileSaved) {
    fileSaved_ = fileSaved;
  }

  public int[][] getTable() {
    return table_;
  }

  public int runCount() {
    return table_.length;
  }

  public int stopCount() {
    return table_.length > 0 ? table_[0].length : 0;
  }

  public int getTime(int run, int stop) {
    //System.out.println("gt run : "+run+" stop: "+stop+" of "+table_[run].length);
    return table_[run][stop];
  }

  public void setTime(int run, int stop, int time) {
    table_[run][stop] = time;
  }

  public int runsPerHour(int h) {
    if (table_.length == 0 || table_[0].length == 0) {
      return 0;
    }
    int c = 0;
    for (int r = 0; r < table_.length; r++) {
      int time = table_[r][0];
      if (time / 3600 == h) {
        c++;
      }
    }
    return c;
  }

  public double averageHeadway(int h) {
    int rph = runsPerHour(h);
    if(rph == 0) return 0;
    if(rph == 1) return 60;

    int headwaySum = 0;
    for(int r = 0; r < table_.length-1; r++) {
      int time1 = table_[r][0], time2 = table_[r+1][0];
      if (time1/3600 == h && time2/3600 == h) {
        headwaySum += (time2-time1)/60;
      }
    }
    double headwaySumDbl = headwaySum, rphDbl = rph;
    return headwaySumDbl / (rph-1);
  }

  public double averageSpeed(int h, SubRoute sub) {
    if (table_.length == 0 || table_[0].length == 0) {
      return 0;
    }
    int c = 0;
    double speedSum = 0;
    double distMi = ((double) sub.getPath().lengthFt(true)) / 5280.0;
    for (int r = 0; r < table_.length; r++) {
      int time = table_[r][0];
      if (time / 3600 == h) {
        double durationHr = (table_[r][table_[r].length-1] - table_[r][0]) / 3600.0;
        double mph = distMi / durationHr;
        //System.out.println("mph="+mph);
        speedSum += mph;
        c++;
      }
    }
    return speedSum / (double) c;
  }

  public int offset(int h) {
    if(runsPerHour(h) == 0) return -1;
    int lowest = 60;
    for (int r = 0; r < table_.length; r++) {
      int time = table_[r][0];
      if (time / 3600 == h) {
        lowest = Math.min(lowest, (time / 60) % 60);
      }
    }
    return (lowest < 60) ? lowest : -1;
  }

  /*public static DayOfWeek toDayOfWeek(int code) {
    switch(code) {
      case 1: return DayOfWeek.WEEKDAY;
      case 2: return DayOfWeek.SATURDAY;
      case 3: return DayOfWeek.SUNDAY;
    }
    return null;
  } 

  public static DayOfWeek toDayOfWeek(String str) {
    str = str.toLowerCase();
    if(str.startsWith("w")) return DayOfWeek.WEEKDAY;
    if(str.startsWith("sa")) return DayOfWeek.SATURDAY;
    if(str.startsWith("su")) return DayOfWeek.SUNDAY;
    return null;
  }*/
    
  public void dbgPrintOneRow() {
    if (runCount() == 0) {
      System.out.println("(empty timetable)");
    } else {
      for (int s = 0; s < stopCount(); s++) {
        System.out.print(table_[0][s] + " ");
      }
      System.out.print("\n");
    }
  }
}























